package com.geek.factory.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.geek.factory.constant.MessageConstant;
import com.geek.factory.constant.SuccessConstant;
import com.geek.factory.dto.InvoiceQueryDTO;
import com.geek.factory.dto.InvoiceRequestDTO;
import com.geek.factory.dto.InvoiceResponseDTO;
import com.geek.factory.entity.Orders;
import com.geek.factory.entity.Invoice;
import com.geek.factory.result.Result;
import com.geek.factory.service.InvoiceService;
import com.geek.factory.service.NuonuoInvoiceService;
import com.geek.factory.service.OrdersService;
import com.geek.factory.utils.NumberToChinese;
import com.geek.factory.vo.TInvoiceQueryVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 增值税发票信息 前端控制器
 * </p>
 *
 * @author author
 * @since 2025-06-20
 */
@RestController
@RequestMapping("/invoices")
@Api(tags = "后台系统的 - 合同模块 - 发票管理")
@Slf4j
public class InvoiceController {

    @Autowired
    private InvoiceService invoiceService;

    @Autowired
    private NuonuoInvoiceService nuonuoInvoiceService;

    @Autowired
    private OrdersService ordersService;

    @ApiOperation("通过ID查询发票信息")
    @GetMapping("{id}")
    public Result findInvoiceById(@ApiParam("发票ID") @PathVariable("id") String id) {
        Invoice tinvoice = invoiceService.getById(id);
        log.info("tinvoice: {}", tinvoice);
        if (tinvoice != null) {
            return new Result(SuccessConstant.SUCCESS, "查询成功", tinvoice);
        }
        return new Result(SuccessConstant.FAIL, "查询失败");
    }

    @ApiOperation("新增发票")
    @PostMapping("add")
    public Result addInvoice(@ApiParam("发票信息") @RequestBody Invoice invoice) {
        log.info("接收到的发票数据: {}", invoice);

        // 简单验证必填项
        if (!StringUtils.hasText(invoice.getCode()) || !StringUtils.hasText(invoice.getNumber())) {
            return new Result(SuccessConstant.FAIL, "缺少发票代码或发票号码");
        }

        boolean saved = invoiceService.save(invoice);
        if(saved){
            return new Result(SuccessConstant.SUCCESS, "新增成功");
        }
        return new Result(SuccessConstant.FAIL, "新增失败");
    }

    @ApiOperation("删除发票")
    @DeleteMapping("{id}")
    public Result deleteInvoice(@ApiParam("发票ID") @PathVariable("id") String id) {
        boolean deleted = invoiceService.removeById(id);
        log.info("delete result: {}", deleted);
        return deleted
                ? new Result(SuccessConstant.SUCCESS, "删除成功")
                : new Result(SuccessConstant.FAIL, "删除失败");
    }

    @ApiOperation("修改发票")
    @PutMapping
    public Result updateInvoice(@ApiParam("发票信息") @RequestBody Invoice invoice) {
        boolean updated = invoiceService.updateById(invoice);
        log.info("update result: {}", updated);
        return updated
                ? new Result(SuccessConstant.SUCCESS, "修改成功")
                : new Result(SuccessConstant.FAIL, "修改失败");
    }

    @ApiOperation("分页查询发票列表")
    @PostMapping("list")
    public Result findInvoicePage(
            @ApiParam("当前页码") @RequestParam(value = "current", required = false, defaultValue = "1") Integer current,
            @ApiParam("每页数量") @RequestParam(value = "size", required = false, defaultValue = "10") Integer size,
            @ApiParam("查询条件") @RequestBody(required = false) TInvoiceQueryVO queryVO
    ) {
        Page<Invoice> page = new Page<>(current, size);
        LambdaQueryWrapper<Invoice> wrapper = new LambdaQueryWrapper<>();

        // 添加查询条件
        if (queryVO != null) {
            if (StringUtils.hasText(queryVO.getCode())) {
                wrapper.like(Invoice::getCode, queryVO.getCode());
            }
            if (StringUtils.hasText(queryVO.getBuyerName())) {
                wrapper.like(Invoice::getBuyerName, queryVO.getBuyerName());
            }
            if (StringUtils.hasText(queryVO.getSellerName())) {
                wrapper.like(Invoice::getSellerName, queryVO.getSellerName());
            }
            if (StringUtils.hasText(queryVO.getType())) {
                wrapper.eq(Invoice::getType, queryVO.getType());
            }
            // 金额范围查询
            if (queryVO.getMinAmount() != null) {
                wrapper.ge(Invoice::getAmountInFiguers, queryVO.getMinAmount().toString());
            }
            if (queryVO.getMaxAmount() != null) {
                wrapper.le(Invoice::getAmountInFiguers, queryVO.getMaxAmount().toString());
            }
        }

        Page<Invoice> result = invoiceService.page(page, wrapper);

        // 处理无数据情况
        if (result.getRecords().isEmpty()) {
            return new Result(SuccessConstant.SUCCESS, "没有查询到数据", result);
        }

        return new Result(SuccessConstant.SUCCESS, "查询成功", result);
    }


    /**
     * 标准开票接口 - 支持前端调用
     */
    @PostMapping("applyByOrder")
    @ApiOperation("申请开具发票")
    public Result applyByOrder(
            @RequestParam String orderNo,
            @RequestParam String buyerName,
            @RequestParam(required = false) String buyerTaxCode,
            @RequestParam(required = false) String buyerAddressPhone,
            @RequestParam(required = false) String buyerBankAccount,
            @RequestParam(required = false) String sellerName,
            @RequestParam(required = false) String sellerTaxCode,
            @RequestParam(required = false) String sellerAddressPhone,
            @RequestParam(required = false) String sellerBankAccount,
            @RequestParam(required = false) String remark,
            @RequestParam(required = false) String checkCode,
            @RequestParam(required = false) String machineCode,
            @RequestParam(required = false, defaultValue = "增值税专用发票") String type,
            @RequestParam(required = false) String receiptor,
            @RequestParam(required = false) String issuer,
            @RequestParam(required = false) String reviewer,
            @RequestParam(required = false, defaultValue = "1000.00") String amount,
            @RequestParam(required = false, defaultValue = "水费") String goodsName,
            @RequestParam(required = false, defaultValue = "1") String quantity,
            @RequestParam(required = false, defaultValue = "吨") String unit,
            @RequestParam(required = false, defaultValue = "0.06") String taxRate
    ) {
        try {
            log.info("申请开具发票，订单号：{}，购方名称：{}", orderNo, buyerName);

            // 参数验证
            if (orderNo == null || orderNo.trim().isEmpty() || buyerName == null || buyerName.trim().isEmpty()) {
                return new Result(SuccessConstant.FAIL, "订单号和购方名称不能为空");
            }

            // 构建发票明细
            InvoiceRequestDTO.InvoiceDetailDTO detail = new InvoiceRequestDTO.InvoiceDetailDTO();
            detail.setTaxRate(taxRate);
            detail.setInvoiceLineProperty("0");
            detail.setSelfCode("服务");
            detail.setListName("企业");
            detail.setSpecType("水费缴费");
            detail.setGoodsName(goodsName);
            detail.setGoodsCode("3040801");
            detail.setTaxExcludedAmount(amount);
            detail.setWithTaxFlag("1");
            detail.setNum(quantity);
            detail.setTax(""); // 自动计算
            detail.setUnit(unit);
            detail.setDeduction("0");
            detail.setPrice(amount);

            List<InvoiceRequestDTO.InvoiceDetailDTO> details = new ArrayList<>();
            details.add(detail);

            // 构建请求DTO
            InvoiceRequestDTO requestDTO = new InvoiceRequestDTO();
            requestDTO.setOrderNo(orderNo);
            requestDTO.setBuyerName(buyerName);
            requestDTO.setBuyerAddress(buyerAddressPhone != null ? buyerAddressPhone : "");
            requestDTO.setBuyerTaxNum(buyerTaxCode != null ? buyerTaxCode : "");
            requestDTO.setBuyerPhone(buyerAddressPhone != null ? buyerAddressPhone : "");
            requestDTO.setEmail(""); // 前端没有传递邮箱，使用空字符串
            requestDTO.setInvoiceDetail(details);

            // 调用服务
            InvoiceResponseDTO response = nuonuoInvoiceService.applyInvoice(requestDTO);

            // 格式化当前日期为字符串
            String currentDate = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));

            if ("E0000".equals(response.getCode())) {
                // 申请成功，保存到本地数据库
                Invoice invoice = new Invoice();

                // 设置基本信息
                invoice.setCode(response.getData() != null ? response.getData().getInvoiceCode() : "");
                invoice.setNumber(response.getData() != null ? response.getData().getInvoiceNumber() : "");
                invoice.setCheckCode(response.getData() != null ? response.getData().getCheckCode() : ""); // 新增
                invoice.setMachineCode(response.getData() != null ? response.getData().getMachineCode() : ""); // 新增

                // 设置购方信息
                invoice.setBuyerName(buyerName);
                invoice.setBuyerTaxCode(buyerTaxCode);
                invoice.setBuyerAddressPhone(buyerAddressPhone);
                invoice.setBuyerBankAccount(buyerBankAccount);

                // 设置销方信息
                invoice.setSellerName(sellerName != null ? sellerName : "智慧工厂");
                invoice.setSellerTaxCode(sellerTaxCode != null ? sellerTaxCode : "339901999999142");
                invoice.setSellerAddressPhone(sellerAddressPhone != null ? sellerAddressPhone : "浙江杭州");
                invoice.setSellerBankAccount(sellerBankAccount != null ? sellerBankAccount : "中国工商银行股份有限公司浙江杭州国际社区支行");

                // 设置金额信息
                invoice.setAmountInFiguers(response.getData() != null ? response.getData().getTotalAmount() : amount);

                // 设置发票类型和人员信息
                invoice.setType(type);
                invoice.setReceiptor(receiptor);
                invoice.setIssuer(issuer);
                invoice.setReviewer(reviewer);
                invoice.setRemark(remark);

                // 设置新增字段
                invoice.setCheckCode(checkCode);
                invoice.setMachineCode(machineCode);
                invoice.setTypeOrg(type); // 使用传入的type作为typeOrg

                // 设置日期信息 - 使用字符串格式
                invoice.setDate(LocalDate.parse(currentDate));
                invoice.setAmountInWords(convertAmountToWords(amount));
                invoice.setPassword(""); // 如果需要密码，可以从响应中获取
                invoice.setUrl(response.getData() != null ? response.getData().getPdfUrl() : "");
                invoice.setInvoiceItemId(0L); // 默认值，可根据需要调整

                boolean saved = invoiceService.save(invoice);
                if (saved) {
                    // 更新订单开票状态
                    updateOrderInvoiceStatus(orderNo, true);
                    return new Result(SuccessConstant.SUCCESS, MessageConstant.INVOICE_APPLY_SUCCESS, response);
                } else {
                    return new Result(SuccessConstant.FAIL, "发票申请成功但保存失败");
                }
            } else {
                // 申请失败，也保存失败状态
                Invoice invoice = new Invoice();

                // 设置基本信息
                invoice.setNumber(orderNo); // 使用订单号作为发票号码
                invoice.setCode(""); // 申请失败时没有发票代码

                // 设置购方信息
                invoice.setBuyerName(buyerName);
                invoice.setBuyerTaxCode(buyerTaxCode);
                invoice.setBuyerAddressPhone(buyerAddressPhone);
                invoice.setBuyerBankAccount(buyerBankAccount);

                // 设置销方信息
                invoice.setSellerName(sellerName != null ? sellerName : "智慧工厂");
                invoice.setSellerTaxCode(sellerTaxCode != null ? sellerTaxCode : "339901999999142");
                invoice.setSellerAddressPhone(sellerAddressPhone != null ? sellerAddressPhone : "浙江杭州");
                invoice.setSellerBankAccount(sellerBankAccount != null ? sellerBankAccount : "中国工商银行股份有限公司浙江杭州国际社区支行");

                // 设置金额信息
                invoice.setAmountInFiguers(amount);

                // 设置发票类型和人员信息
                invoice.setType(type);
                invoice.setReceiptor(receiptor);
                invoice.setIssuer(issuer);
                invoice.setReviewer(reviewer);
                invoice.setRemark("诺诺网返回：" + response.getMessage());

                // 设置新增字段（申请失败时为空）
                invoice.setCheckCode("");
                invoice.setMachineCode("");
                invoice.setTypeOrg(type);

                // 设置日期信息 - 使用字符串格式
                invoice.setDate(LocalDate.parse(currentDate));
                invoice.setAmountInWords(convertAmountToWords(amount));
                invoice.setPassword("");
                invoice.setUrl("");
                invoice.setInvoiceItemId(0L);

                invoiceService.save(invoice);
                return new Result(SuccessConstant.FAIL, response.getMessage() != null ? response.getMessage() : MessageConstant.INVOICE_APPLY_FAIL);
            }
        } catch (Exception e) {
            log.error("申请开具发票失败", e);
            return new Result(SuccessConstant.FAIL, MessageConstant.INVOICE_APPLY_FAIL + "：" + e.getMessage());
        }
    }

    /**
     * 将金额转换为中文大写
     */
    private String convertAmountToWords(String amount) {
        try {
            double num = Double.parseDouble(amount);
            return NumberToChinese.convert(num);
        } catch (Exception e) {
            log.warn("金额转换失败: {}", amount, e);
            return "";
        }
    }
    /**
     * 标准查询接口 - 支持前端调用
     */
    @GetMapping("queryByOrderNo")
    @ApiOperation("根据订单号查询发票")
    public Result queryByOrderNo(@RequestParam String orderNo) {
        try {
            log.info("查询发票，订单号：{}", orderNo);

            // 参数验证
            if (orderNo == null || orderNo.trim().isEmpty()) {
                return new Result(SuccessConstant.FAIL, "订单号不能为空");
            }

            // 构建查询DTO
            InvoiceQueryDTO queryDTO = new InvoiceQueryDTO();
            queryDTO.setOrderNo(orderNo);

            // 调用服务
            InvoiceResponseDTO response = nuonuoInvoiceService.queryInvoice(queryDTO);

            // 补全购方信息
            InvoiceResponseDTO.InvoiceDataDTO data = response.getData();
            if (data != null && (data.getBuyerName() == null || data.getBuyerName().isEmpty()
                    || data.getBuyerTaxNum() == null || data.getBuyerTaxNum().isEmpty())) {
                // 从本地数据库查找
                LambdaQueryWrapper<Invoice> wrapper = new LambdaQueryWrapper<>();
                wrapper.eq(Invoice::getNumber, orderNo);
                Invoice invoice = invoiceService.getOne(wrapper, false);
                if (invoice != null) {
                    if (data.getBuyerName() == null || data.getBuyerName().isEmpty()) {
                        data.setBuyerName(invoice.getBuyerName());
                    }
                    if (data.getBuyerTaxNum() == null || data.getBuyerTaxNum().isEmpty()) {
                        data.setBuyerTaxNum(invoice.getBuyerTaxCode());
                    }
                }
            }

            if ("E0000".equals(response.getCode())) {
                return new Result(SuccessConstant.SUCCESS, MessageConstant.INVOICE_QUERY_SUCCESS, response);
            } else {
                return new Result(SuccessConstant.FAIL, response.getMessage() != null ? response.getMessage() : MessageConstant.INVOICE_QUERY_FAIL);
            }
        } catch (Exception e) {
            log.error("查询发票失败", e);
            return new Result(SuccessConstant.FAIL, MessageConstant.INVOICE_QUERY_FAIL + "：" + e.getMessage());
        }
    }

    /**
     * 更新订单开票状态
     */
    private void updateOrderInvoiceStatus(String orderNo, boolean isInvoiced) {
        try {
            LambdaQueryWrapper<Orders> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(Orders::getNumber, orderNo);
            Orders order = ordersService.getOne(wrapper);

            if (order != null) {
                order.setIsInvoiced(isInvoiced);
                ordersService.updateById(order);
                log.info("订单开票状态已更新，订单号：{}，开票状态：{}", orderNo, isInvoiced);
            }
        } catch (Exception e) {
            log.error("更新订单开票状态失败", e);
        }
    }
}
